import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;

import org.gnu.glpk.GLPK;
import org.gnu.glpk.GLPKConstants;
import org.gnu.glpk.SWIGTYPE_p_double;
import org.gnu.glpk.SWIGTYPE_p_int;
import org.gnu.glpk.glp_cpxcp;
import org.gnu.glpk.glp_iocp;
import org.gnu.glpk.glp_prob;

import model.NetworkGraph;
import model.Request;
import model.RequestLinkFactory;
import model.RequestNodeFactory;
import model.ResourceMapping;
import model.Substrate;
import model.components.Link;
import model.components.Node;
import model.components.RequestLink;
import model.components.RequestRouter;
import model.components.RequestSwitch;
import model.components.Server;
import model.components.SubstrateLink;
import model.components.SubstrateRouter;
import model.components.SubstrateSwitch;
import model.components.VirtualMachine;
import model.components.Node.Location;
import tools.NodeComparator;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.graph.util.Pair;
import model.SimulatorConstants;

public class RVine {
	
	private static int  MAX_TYPES = 3;
	
	/** return a collection with the graph nodes **/
	private Collection<Node> getNodes(Graph<Node,Link> t) {
		ArrayList<Node> reqNodes =new ArrayList<Node>();

		for (Node x: t.getVertices())
			reqNodes.add(x);

		return reqNodes;
	}
	
	/** Return a table with the available capacity value between two substrate nodes **/
	private double[][] getAvailableBandwidthTable(Graph<Node,Link> t) {
		
		int numNodes = t.getVertexCount();
		Collection<Link> edges =  t.getEdges();
		
		double[][] capacityTable =  new double[numNodes][numNodes];
		
		for (Link current : edges){
			Pair<Node> currentNodes = t.getEndpoints(current);
			
			int node1 = currentNodes.getFirst().getId();
			int node2 = currentNodes.getSecond().getId();
			
			/* Begin add By Simon, error in double[][] tmpReqLinks = getAvailableBandwidthTable(request) */
			//double cap = ((SubstrateLink) current).getAvailableBandwidth();
			System.out.println("current.getBandwidth(): "+current.getBandwidth());
			double cap = current.getBandwidth();
			/* end add */
			
			capacityTable[node1][node2] = cap;
			capacityTable[node2][node1] = cap;
			
			System.out.println("augcaptable["+node2+"]["+node1+"]: "+(1.0/cap));
		}
		
		return capacityTable;
	}
	
	/** Separate nodes by type **/
	private ArrayList<ArrayList<Integer>> createArray (ArrayList<Node> list) {
		ArrayList<ArrayList<Integer>>  tmp = new  ArrayList<ArrayList<Integer>>();
		
		for (int i=0;i<MAX_TYPES;i++)
			tmp.add(new ArrayList<Integer>());
		
		for (int i=0;i<list.size();i++) {   
			if ((list.get(i) instanceof Server))
				tmp.get(0).add(i);
			else  if ((list.get(i) instanceof SubstrateRouter))
				tmp.get(1).add(i);
			else if ((list.get(i) instanceof SubstrateSwitch))
				tmp.get(2).add(i);
			else if ((list.get(i) instanceof VirtualMachine))
				tmp.get(0).add(i); 	 
			else if ((list.get(i) instanceof RequestRouter))
				tmp.get(1).add(i);
			else if ((list.get(i) instanceof RequestSwitch))
				tmp.get(2).add(i);
		}
		return tmp;
	}
	
	/** Find how many switches, routers and servers or VMs are **/
	private LinkedHashMap<String, Integer> getType (ArrayList<Node> list) {
		LinkedHashMap<String, Integer>  tmp = new LinkedHashMap<String, Integer> ();

	    for (int i=0;i<list.size();i++){   
		     if ((list.get(i) instanceof Server) ) {
		    	 	if (tmp.containsKey("Server")==false)
		    	 		tmp.put("Server", 1);
		    	 	else 	    	 
		    	 		tmp.put("Server", tmp.get("Server")+1);
		    	 }
		     else  if ((list.get(i) instanceof SubstrateRouter) ) {
		    	 	if (tmp.containsKey("SubstrateRouter")==false)
		    	 		tmp.put("SubstrateRouter", 1);
		    	 	else 	    	 
		    	 		tmp.put("SubstrateRouter", tmp.get("SubstrateRouter")+1);
		    	 }
		     else if ((list.get(i) instanceof SubstrateSwitch) ) {
		    	 	if (tmp.containsKey("SubstrateSwitch")==false)
		    	 		tmp.put("SubstrateSwitch", 1);
		    	 	else 	    	 
		    	 		tmp.put("SubstrateSwitch", tmp.get("SubstrateSwitch")+1);
		    	 }
		     else if ((list.get(i) instanceof VirtualMachine) ){
		    	 	if (tmp.containsKey("VirtualMachine")==false)
		    	 		tmp.put("VirtualMachine", 1);
		    	 	else 	    	 
		    	 		tmp.put("VirtualMachine", tmp.get("VirtualMachine")+1);
		    	 }
		    	 
		     else if ((list.get(i) instanceof RequestRouter) ){
		    	 	if (tmp.containsKey("RequestRouter")==false)
		    	 		tmp.put("RequestRouter", 1);
		    	 	else 	    	 
		    	 		tmp.put("RequestRouter", tmp.get("RequestRouter")+1);
		    	 }
		     else if ((list.get(i) instanceof RequestSwitch) ) {
		    	 	if (tmp.containsKey("RequestSwitch")==false)
		    	 		tmp.put("RequestSwitch", 1);
		    	 	else 	    	 
		    	 		tmp.put("RequestSwitch", tmp.get("RequestSwitch")+1);
		    	 }
		   }
		    
	    return tmp;
	}
	
	public int[][] getCapacities (ArrayList<Node> list){
		int[][] tmp =  new int[3][list.size()];

		for (int i=0;i<list.size();i++){  
		if ((list.get(i) instanceof VirtualMachine) ){
			tmp[0][i]= ((VirtualMachine)list.get(i)).getCpu();
			tmp[1][i]=((VirtualMachine)list.get(i)).getMemory();
			tmp[2][i]=((VirtualMachine)list.get(i)).getDiskSpace();
		}
		if ((list.get(i) instanceof RequestRouter) ){
			tmp[0][i]=1;
			}
		if ((list.get(i) instanceof RequestSwitch) ){
			tmp[0][i]=((RequestSwitch)list.get(i)).getCpu();
			tmp[1][i]=((RequestSwitch)list.get(i)).getMemory();
			}
		if ((list.get(i) instanceof Server) ){
			tmp[0][i]= ((Server)list.get(i)).getCpu();
			tmp[1][i]=((Server)list.get(i)).getMemory();
			tmp[2][i]=((Server)list.get(i)).getDiskSpace();
		}
		if ((list.get(i) instanceof SubstrateRouter) ){
			tmp[0][i]=((SubstrateRouter)list.get(i)).getLogicalInstances();
			}
		if ((list.get(i) instanceof SubstrateSwitch) ){
			tmp[0][i]=((SubstrateSwitch)list.get(i)).getCpu();
			tmp[1][i]=((SubstrateSwitch)list.get(i)).getMemory();
			}

		}

		return tmp;
	}
	
	/** Return a table with the bandwidth value between two nodes 
	 * [n1][n2] = bw
	 * [n2][n1] = -bw
	 * **/
	private double[][] getBandwidthTable(Graph<Node,Link> t) {
		int num = t.getVertexCount();
		Collection<Link> edges =  t.getEdges();
		double[][] tab =  new double[num][num];
		
		for (Link current : edges){
			Pair<Node> currentNodes =t.getEndpoints(current);
			int node1 = currentNodes.getFirst().getId();
			int node2= currentNodes.getSecond().getId();
			double cap = current.getBandwidth();
			tab[node1][node2] = cap;
			tab[node2][node1] = -cap;
		}
		return tab;
	}
	
	private double avgHops(double[][][] flow){
		double avgHops =0;
		
		for (int k=0; k< flow.length;k++){
			int hop_count=0;
			for (int i=0; i<flow[k].length;i++) {
				for (int j=0; j<flow[k][i].length;j++){
					if (flow[k][i][j]>0){						
						hop_count++;
					}
				}
			}
			avgHops +=hop_count;
		}
		
		return avgHops/flow.length;
	}
	
	private double Cost_Embedding(double[][][] flow, Graph<Node, Link> request, Graph<Node, Link> substrate){
		double cost=0;
		for (int k=0;k<flow.length;k++){
			for (int i=0;i<substrate.getVertexCount();i++){
				for (int j=0;j<substrate.getVertexCount();j++){
					cost=cost+flow[k][i][j];
				}
			}
		}
		  
		if (cost!=0){
			for (Node x: request.getVertices()){
				for (int m=0;m<3;m++){
					if (x instanceof VirtualMachine)
						cost=cost+x.getCpu()+x.getMemory()+((VirtualMachine)x).getDiskSpace();
					else if (x instanceof RequestRouter)
						cost=cost+x.getCpu()+x.getMemory();
					else if (x instanceof RequestSwitch)
						cost=cost+x.getCpu()+x.getMemory();
				}
			}
		}

		return cost;
	}
	
	public Graph<Node, Link> getCopy(Graph<Node, Link> t) {
		NetworkGraph g = new NetworkGraph();
		for (Link link : t.getEdges()) {
			Link l = (Link) link.getCopy();
			Pair<Node> endpoints = t.getEndpoints(link);
			Node n1 = g.getVertexByName(endpoints.getFirst().getName());
			if (n1==null)
				n1 = (Node) endpoints.getFirst().getCopy();
			Node n2 = g.getVertexByName(endpoints.getSecond().getName());
			if (n2==null)
				n2 = (Node) endpoints.getSecond().getCopy();
			g.addEdge(l,n1,n2);
		}
		return g;
	}
	
	public 	LinkedHashMap<Node, Node> myNodeMapping(ArrayList<Node> substrate, Graph<Node, Link> realSub, Collection<Node> request, int reqLinksNum, Double[][][] xVar, Double[][][] fVar){
		LinkedHashMap<Node, Node> phi = new LinkedHashMap<Node, Node>(); // request-real
		//augmented substrate
		/* Variable fai is not used */
		double[] fai = new double[realSub.getVertexCount()];
		double[] pai = new double[realSub.getVertexCount()];
		boolean ctrl = true;
		
		System.out.println("request.getSize: "+request.size());
		System.out.println("substrate.getSize: "+substrate.size());
		
		for (Node node : request) {
			double max=0;
			int index_max=0;
			Node selected=null;
			for (Node subNode : substrate){
				System.out.println(node.getType()+" <-> "+subNode.getType());
				if (node.getType().equalsIgnoreCase(subNode.getType())){
					System.out.println("success");
					for (int k=0;k<reqLinksNum;k++){
							System.out.println("xVar["+k+"]["+node.getId()+"]["+subNode.getId()+"]: "+xVar[k][node.getId()][subNode.getId()]);
							pai[subNode.getId()-request.size()] += (fVar[k][node.getId()][subNode.getId()]+fVar[k][subNode.getId()][node.getId()])*xVar[k][node.getId()][subNode.getId()];
					}
					System.out.println("pai[subNode.getId()-request.size()]: "+pai[subNode.getId()-request.size()]);
					/* Variable fai Is not used */
					System.out.println("fai[subNode.getId()-request.size()]: "+fai[subNode.getId()-request.size()]);
					if (pai[subNode.getId()-request.size()]>max && fai[subNode.getId()-request.size()]==0){
						System.out.println("enter");
						max = pai[subNode.getId()-request.size()];
						index_max = subNode.getId()-request.size();
						selected=subNode;
						System.out.println("max: "+max);
					}
				}
			}
			if (max!=0) {
				fai[index_max]=1;
				System.out.println("selected: "+selected);
				phi.put(node, selected);
			} else {
				System.out.println("node can not be mapped");
				ctrl=false;
			}
		}
		if (ctrl)
			return phi;
		else
			return null;
	}
	
	public LinkedList<LinkedHashMap<Node, Node>> embed(Graph<Node, Link> request, Graph<Node, Link> substrate) {
		boolean denied = false;
		int denials1=0;
		int denials2=0;
		int algo_denials = 0;
		int denial=0;
		double[][][] fi = new double[request.getEdgeCount()][substrate.getVertexCount()][substrate.getVertexCount()];
		LinkedHashMap<Node, Node> nodeMapping = new LinkedHashMap<Node,Node>();
		
		Graph<Node, Link> substrateCopy = getCopy(substrate);
		Substrate augmentedSubstrate = new Substrate("augmentedSubstrate");
		
		//change ids in substrate copy
		for (Node n: getNodes(substrateCopy)){
			int current_id = n.getId();
			n.setId(current_id+request.getVertexCount());
		}
		
		/* add substrate to augmented graph */
		for (Link current : substrateCopy.getEdges()){
			Pair<Node> x =  substrateCopy.getEndpoints(current);
			augmentedSubstrate.getGraph().addEdge(current, x.getFirst(), x.getSecond(), EdgeType.UNDIRECTED);
			augmentedSubstrate.getGraph().addVertex(x.getFirst());
			augmentedSubstrate.getGraph().addVertex(x.getSecond());
		}

		/* add request to augmented graph */
		Collection<Node> tmpReqNodes = getNodes(request);
		int subLinkNum = augmentedSubstrate.getGraph().getEdgeCount();

		for (Node x : tmpReqNodes) {
			augmentedSubstrate.getGraph().addVertex(x);
			for (Node subNode : getNodes(substrateCopy)) {
				int LinkID = subLinkNum++;
				SubstrateLink l = new SubstrateLink(LinkID,(int) 2.147483647E5);
				augmentedSubstrate.getGraph().addEdge(l, x, subNode, EdgeType.UNDIRECTED);
			}
		}
		
		System.out.println("getVertexCount: "+augmentedSubstrate.getGraph().getVertexCount());
		double[][] augCapTable = getAvailableBandwidthTable(augmentedSubstrate.getGraph());
		
		System.out.println("augCapTable: "+augCapTable);

		try {
			glp_prob prob = GLPK.glp_create_prob();
			GLPK.glp_set_prob_name(prob, "rVine");
			GLPK._glp_lpx_set_real_parm(prob, GLPK.LPX_K_TMLIM, 600);
			GLPK._glp_lpx_set_real_parm(prob, GLPK.LPX_K_OBJUL, Double.MAX_VALUE);
			GLPK._glp_lpx_set_real_parm(prob, GLPK.LPX_K_OBJLL, -1*Double.MAX_VALUE);
			
			/*IloCplex cplex = new IloCplex();
			cplex.setParam(IloCplex.DoubleParam.TiLim, 15);
			IloCplex cplex1 = new IloCplex();
			cplex1.setParam(IloCplex.DoubleParam.TiLim, 15);*/
			 
			 // substate copy has changed ids
			ArrayList<Node> tmpSubNodesList = new ArrayList<Node>();
			tmpSubNodesList = (ArrayList<Node>) getNodes(substrateCopy);
			Collections.sort(tmpSubNodesList, new NodeComparator());

			ArrayList<Node> tmpReqNodesList = new ArrayList<Node>();
			tmpReqNodesList = (ArrayList<Node>) getNodes(request);
			Collections.sort(tmpReqNodesList, new NodeComparator());
		
			int initSubNodeNum = tmpSubNodesList.size();
			int reqNodeNum = tmpReqNodes.size();
			int reqLinksNum = request.getEdgeCount();
			int augGraph = initSubNodeNum+reqNodeNum;
			
			//create x,f continuous variables, all with bounds lb and ub
			
			String name;
			
			// (2)
			
			int[][][] f = new int[reqLinksNum][][];
			int[][][] x = new int[reqLinksNum][][];
				
			for(int k=0; k<reqLinksNum; k++) {
				f[k] = new int[augGraph][];
				x[k] = new int[augGraph][];
				for (int u=0; u<augGraph; u++){
					f[k][u] = new int[augGraph];
					x[k][u] = new int[augGraph];
					for (int v=0; v<augGraph; v++){
						if(u==v)
							continue;
						
						f[k][u][v] = GLPK.glp_add_cols(prob, 1);
	                    name = "f[" + k + "," + u + "," + v + "]";
	                    GLPK.glp_set_col_name(prob, f[k][u][v], name);
	                    GLPK.glp_set_col_kind(prob, f[k][u][v], GLPKConstants.GLP_CV);
	                    GLPK.glp_set_col_bnds(prob, f[k][u][v], GLPKConstants.GLP_DB, 0, Double.MAX_VALUE);
	                    
	                    x[k][u][v] = GLPK.glp_add_cols(prob, 1);
	                    name = "x[" + k + "," + u + "," + v + "]";
	                    GLPK.glp_set_col_name(prob, x[k][u][v], name);
	                    GLPK.glp_set_col_kind(prob, x[k][u][v], GLPKConstants.GLP_BV);
					}
				}
			}
			
			System.out.println((reqLinksNum*augGraph*augGraph)*2+" variables");
			System.out.println("augGraph: "+augGraph);
			System.out.println("reqLinksNum: "+reqLinksNum);
			
			/* IloNumVar[][][] f = new IloNumVar[reqLinksNum][][];
			for (int k=0;k<reqLinksNum;k++){
				f[k]=new IloNumVar[augGraph][];
				for (int u=0; u<augGraph; u++){
					f[k][u]=cplex.numVarArray(augGraph, 0, Double.MAX_VALUE);
				}
			}
			
			IloNumVar[][][] x = new IloNumVar[reqLinksNum][][];
			for (int k=0;k<reqLinksNum;k++){
				x[k]=new IloNumVar[augGraph][];
				for (int u=0; u<augGraph; u++){
					x[k][u]=cplex.numVarArray(augGraph, 0, 1);
				}
			}*/
			
			// (1a) - Flows
			for (int u=reqNodeNum; u<augGraph; u++) { 
				for (int v=reqNodeNum; v<augGraph; v++) {
					for (int k =0; k<reqLinksNum; k++) {
						System.out.println("coef f["+u+"]["+v+"]: "+augCapTable[u][v]+" "+Double.MIN_VALUE+" -> "+(1.0/(augCapTable[u][v]+Double.MIN_VALUE)));
						GLPK.glp_set_obj_coef(prob, f[k][u][v], 1.0/(augCapTable[u][v]+Double.MIN_VALUE));
					}
				}
			}
			
			/*IloLinearNumExpr flows = cplex.linearNumExpr();
			for (int i=reqNodeNum;i<augGraph; i++){ 
				for (int j=reqNodeNum;j<augGraph; j++){
					for (int k =0; k<reqLinksNum; k++) {
					flows.addTerm(1.0/(augCapTable[i][j]+Double.MIN_VALUE), f[k][i][j]);
					//flows.addTerm(1.0, f[k][i][j]);
					}
				}
			}*/

			///////////////////////////revise////////////////////////////////////////////////////////
			/////////////////////////////////////////////////////////////////////

			///////////////////////////////////////////////////
			//Find how many routers and servers we have///////
			/////////////////////////////////////////////////
			LinkedHashMap<String, Integer> tmp_req = getType(tmpReqNodesList);
			int v_types =  tmp_req.size();
			/////////////////
			LinkedHashMap<String, Integer> tmp_sub = getType(tmpSubNodesList);
			int s_types =  tmp_sub.size();
			int[] ctypes=new int[s_types];
			ctypes[0]=1;

			ArrayList<ArrayList<Integer>> Vv = createArray(tmpReqNodesList);
			ArrayList<ArrayList<Integer>> Vs = createArray(tmpSubNodesList);
		    
			System.out.println("Vv: "+Vv);
			System.out.println("Vs: "+Vs);
			////////////////////////////////////////////////////////////////
			//Build arrays for the different functional characteristics////
			//////////////////////////////////////////////////////////////
			int[][] Vcost = getCapacities(tmpReqNodesList);
			int[][] Scost = getCapacities(tmpSubNodesList);

			///////////////////////////////revise/////////////////////////////////////////////////

			////////////////////////////////////////////////////////////
			//building the second summation of the objective function//
			//////////////////////////////////////////////////////////
			// (1b) - Capacities
			for (int k=0;k<reqLinksNum;k++) {
				for (int i=0;i<v_types;i++) {
					for (int w : Vs.get(i)) {
						for (int m : Vv.get(i)){
							double total_cap=0;
							for (int j=0;j<3;j++){
								total_cap = (total_cap+Vcost[j][m]/(Scost[j][w]+Double.MIN_VALUE));
							}
							//System.out.println("coef x: "+total_cap+" "+Double.MIN_VALUE+" -> "+(Vcost[j][m]/(Scost[j][w]+Double.MIN_VALUE)));
							GLPK.glp_set_obj_coef(prob, x[k][m][w+reqNodeNum], total_cap);
						}				
					}
				}	
			}
			
			/*
			IloLinearNumExpr capacities = cplex.linearNumExpr();
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<v_types;i++){
					for (int w : Vs.get(i)){
						for (int m : Vv.get(i)){
							double total_cap=0;
							for (int j=0;j<3;j++){
								//capacities.addTerm(Vcost[j][m]/(Scost[j][w]+Double.MIN_VALUE), x[k][m][w+reqNodeNum]);
								total_cap= ((total_cap+Vcost[j][m]/(Scost[j][w]+Double.MIN_VALUE)));
							}
							capacities.addTerm(total_cap,x[k][m][w+reqNodeNum]);
						}
					}
				}
			}
			*/
			
			// (1c) -
			// (second summation) ax + by + ... + (third summation) x = (1+a)x + by + ...
			
			for (int k=0;k<reqLinksNum;k++) {
				for (int u=reqNodeNum; u<augGraph; u++){
					for (int v=reqNodeNum; v<augGraph; v++){
						double value = GLPK.glp_get_obj_coef(prob, x[k][u][v]);
						GLPK.glp_set_obj_coef(prob, x[k][u][v], 1+value);
					}
				}	
			}
			
			// (1c*) TODO why are you doing cplex.prod(x[0][0][0],0) least reqLinksNum times?
			
			/*//Third summation
			IloNumExpr hops =cplex.prod(x[0][0][0],0);
			for (int k=0;k<reqLinksNum;k++){
				IloNumExpr expr1 =cplex.prod(x[0][0][0],0);
				for (int i=reqNodeNum;i<augGraph;i++){
					for (int j=reqNodeNum;j<augGraph;j++){
						expr1=cplex.sum(expr1,x[k][i][j]);
					}
				}
				hops = cplex.sum(hops, expr1);
			}*/
			
			
			//The objective function
			//IloNumExpr expr = cplex.sum(flows, capacities);
			//expr = cplex.sum(expr,hops);

			//create objective minimization
			/* cplex.addMinimize(expr); */
			
			SWIGTYPE_p_int ind;
		    SWIGTYPE_p_double val;
			
			/*// (5) -> f[k][u][v] + f[k][v][u] - capacity*x[k][u][v] <= 0
			for (int k=0; k<reqLinksNum; k++){
				for (int u=0; u<augGraph; u++){
					for (int v=u+1; v<augGraph; v++){
						double capacity = augCapTable[u][v];
						
						int constraint = GLPK.glp_add_rows(prob, 1);
						GLPK.glp_set_row_name(prob, constraint, "r_(5)_"+constraint);
						System.out.println("r_(5)_"+constraint+" f["+k+"]["+u+"]["+v+"]");
						GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_UP, 0, 0);
						ind = GLPK.new_intArray(4);
						GLPK.intArray_setitem(ind, 1, f[k][u][v]);
					    GLPK.intArray_setitem(ind, 2, f[k][v][u]);
					    GLPK.intArray_setitem(ind, 3, x[k][u][v]);
					    val = GLPK.new_doubleArray(4);
					    GLPK.doubleArray_setitem(val, 1, 1);
					    GLPK.doubleArray_setitem(val, 2, 1);
					    GLPK.doubleArray_setitem(val, 3, -capacity);
					    GLPK.glp_set_mat_row(prob, constraint, 3, ind, val);	
					}
				}		
			}*/

			/*//////////////////////////////////////////////////////////
			//Link constraint////////////////////////////////////////
			////////////////////////////////////////////////////////
			for (int k=0;k<reqLinksNum; k++){
				for (int i=0;i<augGraph; i++){
					for (int j=0;j<augGraph; j++){
						IloNumExpr flowSum = cplex.prod(x[0][0][0],0);
						IloLinearNumExpr availBW = cplex.linearNumExpr();
						flowSum = cplex.sum(cplex.prod(f[k][i][j],1), 
								cplex.prod(f[k][j][i],1));
						
						double capacity = augCapTable[i][j];
						availBW.addTerm(capacity, x[k][i][j]);
						cplex.addLe(flowSum, availBW);	
					}
				}		
			}*/
			
			// (6) -> sum{in k}(f[k][u][v] + f[k][v][u]) <= capacity
			for (int u=0; u<augGraph; u++){
				for (int v=u+1; v<augGraph; v++){
					double capacity = augCapTable[u][v];
					int constraint = GLPK.glp_add_rows(prob, 1);
					GLPK.glp_set_row_name(prob, constraint, "r_(6)_"+constraint);
					GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_UP, 0, capacity);
					ind = GLPK.new_intArray(2*reqLinksNum+1);
					val = GLPK.new_doubleArray(2*reqLinksNum+1);
					
					for (int k=0; k<reqLinksNum; k++) {
						int idx = (k+1)*2;
					    GLPK.intArray_setitem(ind, idx-1, f[k][u][v]);
					    GLPK.intArray_setitem(ind, idx, f[k][v][u]);
					    GLPK.doubleArray_setitem(val, idx-1, 1);
					    GLPK.doubleArray_setitem(val, idx, 1);
					}
					
					GLPK.glp_set_mat_row(prob, constraint, 2*reqLinksNum, ind, val);
				}		
			}
			
			/*//Link Constraint 2
			for (int i=0;i<augGraph; i++){
				for (int j=0;j<augGraph; j++){
					IloNumExpr expr1 =cplex.prod(x[0][0][0],0);
					IloNumExpr flowSum =cplex.prod(x[0][0][0],0);
					
					for (int k=0;k<reqLinksNum; k++){
						flowSum = cplex.sum(cplex.prod(f[k][i][j],1), 
								cplex.prod(f[k][j][i],1));
						expr1 =cplex.sum(expr1,flowSum);
					}
					double capacity = augCapTable[i][j];				
					cplex.addLe(expr1,capacity);
				}
			}*/
			
			//node constraint for virtual machines and servers
			
			// (7) 
			
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<s_types;i++){
					for (int w : Vs.get(i)){
						for (int m : Vv.get(i)){
							for (int j=0;j<3;j++){			
								double cpuSub = Scost[j][w];
								int constraint = GLPK.glp_add_rows(prob, 1);
								GLPK.glp_set_row_name(prob, constraint, "r_(7)_"+constraint);
								GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_UP, 0, cpuSub);
								ind = GLPK.new_intArray(2);
								GLPK.intArray_setitem(ind, 1, x[k][m][w+reqNodeNum]);
							    val = GLPK.new_doubleArray(2);
							    GLPK.doubleArray_setitem(val, 1, Vcost[j][m]);
							    GLPK.glp_set_mat_row(prob, constraint, 1, ind, val);
							}
						}
					}
				}
			}
			
			/*
			  for (int k=0;k<reqLinksNum;k++){
					for (int i=0;i<s_types;i++){
						for (int w : Vs.get(i)){
							for (int m : Vv.get(i)){
								for (int j=0;j<3;j++){
									//IloNumExpr xSum =cplex.prod(x[0][0][0],0);
									//xSum=cplex.sum(xSum,x[k][m][w+reqNodeNum]);
									double cpuSub=Scost[j][w];
									//cplex.addLe(cplex.prod(Vcost[j][m],xSum),cpuSub);
									cplex.addLe(cplex.prod(Vcost[j][m], x[k][m][w+reqNodeNum]),cpuSub);
								}
							}
						}
					}
				}
			 */
			
			/*for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<s_types;i++){
					for (int w : Vs.get(i)){
						for (int m : Vv.get(i)){
							for (int j=0;j<ctypes[i];j++){
								double ccost=Scost[j][w];
								double vcost=Vcost[j][m];
								int ratio= (int) ( ccost/(vcost+1));
								
								int constraint = GLPK.glp_add_rows(prob, 1);
								GLPK.glp_set_row_name(prob, constraint, "r_(7)_"+constraint);
								GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_UP, 0, ratio);
								ind = GLPK.new_intArray(2);
								GLPK.intArray_setitem(ind, 1, x[k][m][w+reqNodeNum]);
							    val = GLPK.new_doubleArray(2);
							    GLPK.doubleArray_setitem(val, 1, Vcost[j][m]);
							    GLPK.glp_set_mat_row(prob, constraint, 1, ind, val);
							}
						}
					}
				}
			}*/

			/*
			//By Aris
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<s_types;i++){
					for (int w : Vs.get(i)){
						for (int m : Vv.get(i)){
							for (int j=0;j<ctypes[i];j++){
								double ccost=Scost[j][w];
								double vcost=Vcost[j][m];
								int ratio= (int) ( ccost/(vcost+1));
								cplex.addLe(x[k][m][w+reqNodeNum],ratio);
							}
						}
					}
				}
			}
			*/
			
			// (8)
			
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<s_types;i++){
					for (int w : Vs.get(i)){
						/* Begin add by Simon */
						if(Vv.get(i).size() > 0) {
						/* End add */
							int constraint = GLPK.glp_add_rows(prob, 1);
							GLPK.glp_set_row_name(prob, constraint, "r_(8)_"+constraint);
							GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_UP, 0, 1);
							ind = GLPK.new_intArray(Vv.get(i).size()+1);
							val = GLPK.new_doubleArray(Vv.get(i).size()+1);
							int idx = 1;
							for (int m : Vv.get(i)){
								GLPK.intArray_setitem(ind, idx, x[k][m][w+reqNodeNum]);
								System.out.println("r_(8)_"+constraint+": x["+k+"]["+m+"]["+(w+reqNodeNum)+"]: "+x[k][m][w+reqNodeNum]);
							    GLPK.doubleArray_setitem(val, idx, 1);
							    idx++;
							}
							GLPK.glp_set_mat_row(prob, constraint, Vv.get(i).size(), ind, val);
						}
					}
				}
			}
			
			/*
			//Constraint 8
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<s_types;i++){
					for (int w : Vs.get(i)){
						IloLinearNumExpr capReq = cplex.linearNumExpr();
						for (int m : Vv.get(i)){
							capReq.addTerm(1,x[k][m][w+reqNodeNum]);
						}
						cplex.addLe(capReq,1);
					}
				}
			}
			*/
			
			System.out.println("8th constraint 2");
			
			// (8.2)
			
			for (int k=0;k<reqLinksNum;k++){
				for (int m=0;m<reqNodeNum;m++){
					int constraint = GLPK.glp_add_rows(prob, 1);
					GLPK.glp_set_row_name(prob, constraint, "r_(8.2)_"+constraint);
					GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_UP, 0, 1);
					ind = GLPK.new_intArray(augGraph-reqNodeNum+1);
					val = GLPK.new_doubleArray(augGraph-reqNodeNum+1);
					int idx = 1;
					for (int w=reqNodeNum; w<augGraph; w++){
						GLPK.intArray_setitem(ind, idx, x[k][m][w]);
					    GLPK.doubleArray_setitem(val, idx, 1);
					    idx++;
					}
					GLPK.glp_set_mat_row(prob, constraint, augGraph-reqNodeNum, ind, val);
				}
			}

			/*//meta-constraint 9 but in a generic form
			for (int k=0;k<reqLinksNum;k++){
				for (int m=0;m<reqNodeNum;m++){
					IloLinearNumExpr capReq = cplex.linearNumExpr();
						for (int w=reqNodeNum;w<augGraph;w++){
							capReq.addTerm(1, x[k][m][w]);
					}
						cplex.addLe(capReq, 1);
				}
			}*/
			
			System.out.println("10th constraint");
			
			// (10)
			
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<s_types;i++){
					for (int m : Vv.get(i)){
						/* Begin add by Simon */
						if(Vs.get(i).size() > 0) {
						/* End add */
							int constraint = GLPK.glp_add_rows(prob, 1);
							GLPK.glp_set_row_name(prob, constraint, "r_(10)_"+constraint);
							GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_FX, 1, 1);
							ind = GLPK.new_intArray(Vs.get(i).size()+1);
							val = GLPK.new_doubleArray(Vs.get(i).size()+1);
							int idx = 1;
							for (int w : Vs.get(i)){
								GLPK.intArray_setitem(ind, idx, x[k][m][w+reqNodeNum]);
							    GLPK.doubleArray_setitem(val, idx, 1);
							    idx++;
							}
							
							GLPK.glp_set_mat_row(prob, constraint, Vs.get(i).size(), ind, val);
						}
					}
				}
			}
			
			/*
			//Constraint 10
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<s_types;i++){
					for (int m : Vv.get(i)){
						IloLinearNumExpr capReq = cplex.linearNumExpr();
						for (int w : Vs.get(i)){
							capReq.addTerm(1,x[k][m][w+reqNodeNum]);
						}
						cplex.addEq(capReq,1);
					}
				}
			}
			*/
			
			System.out.println("11th constraint");
			
			// (11)
			
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<augGraph; i++){
					for (int j=i+1;j<augGraph; j++){
						/* Begin add by Simon */
						//if(i == j)
						//	continue;
						/* End add */
						
						int constraint = GLPK.glp_add_rows(prob, 1);
						GLPK.glp_set_row_name(prob, constraint, "r_(11)_"+constraint);
						GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_FX, 0, 0);
						ind = GLPK.new_intArray(3);
						val = GLPK.new_doubleArray(3);
						GLPK.intArray_setitem(ind, 1, x[k][i][j]);
						GLPK.intArray_setitem(ind, 2, x[k][j][i]);
						GLPK.doubleArray_setitem(val, 1, 1);
						GLPK.doubleArray_setitem(val, 2, -1);
						GLPK.glp_set_mat_row(prob, constraint, 2, ind, val);
					}
				}
			}

			/*//constraint 11
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<augGraph; i++){
					for (int j=0;j<augGraph; j++){
							IloLinearNumExpr capReq1 = cplex.linearNumExpr();
							IloLinearNumExpr capReq2 = cplex.linearNumExpr();
							capReq1.addTerm(1, x[k][i][j]);
							capReq2.addTerm(1,x[k][j][i]);
							cplex.addEq(capReq1,capReq2);
					}
				}
			}*/
			
			// (12)
			
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<augGraph;i++){
					for (int j=0;j<augGraph;j++){
						/* Begin add by Simon */
						if(i == j)
							continue;
						/* End add */
						
						int constraint = GLPK.glp_add_rows(prob, 1);
						GLPK.glp_set_row_name(prob, constraint, "r_(12)_"+constraint);
						GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_LO, 0, 0);
						ind = GLPK.new_intArray(4);
						val = GLPK.new_doubleArray(4);
						GLPK.intArray_setitem(ind, 1, x[k][i][j]);
						GLPK.intArray_setitem(ind, 2, f[k][i][j]);
						GLPK.intArray_setitem(ind, 3, f[k][j][i]);
						GLPK.doubleArray_setitem(val, 1, -1);
						GLPK.doubleArray_setitem(val, 2, 1);
						GLPK.doubleArray_setitem(val, 3, 1);
						GLPK.glp_set_mat_row(prob, constraint, 3, ind, val);
					}
				}
			}

			/*
			//Constraint 12
			for (int k=0;k<reqLinksNum;k++){
				for (int i=0;i<augGraph;i++){
					for (int j=0;j<augGraph;j++){
						IloNumExpr flowSum =cplex.prod(x[0][0][0],0);
						IloLinearNumExpr capReq = cplex.linearNumExpr();
						capReq.addTerm(1,x[k][i][j]);
						
							flowSum = cplex.sum(cplex.prod(f[k][i][j],1), 
									cplex.prod(f[k][j][i],1));
									
						
						cplex.addGe(flowSum, capReq);
					}
				}
			}*/
			
			System.out.println("sto per fare i flow constraint");
			
			double[][] demands = getBandwidthTable(request);

			/////////////////////////////////////////////
			//find the origins of the virtual link//////
			///////////////////////////////////////////
			int[] o = new int[reqLinksNum];
			int[] d = new int[reqLinksNum];
			int ct=0;
			for (int i=0;i<reqNodeNum;i++){
				for (int j=0;j<reqNodeNum;j++){
					if ((j>i)&&(demands[i][j]!=0)){
						o[ct]=i;
						d[ct]=j;
						ct++;
					}
				}
			}
			
			// (4.1)
			
			for (int k=0;k<reqLinksNum; k++){
				for (int i=0;i<augGraph; i++){ 
					if (i!=o[k] && i!=d[k]){
						int constraint = GLPK.glp_add_rows(prob, 1);
						GLPK.glp_set_row_name(prob, constraint, "r_(4.1)_"+constraint);
						GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_FX, 0, 0);
						ind = GLPK.new_intArray(augGraph*2+1);
						val = GLPK.new_doubleArray(augGraph*2+1);
						int idx = 1;
						for (int j=0; j<augGraph; j++){
							/* Begin add by Simon */
							if(i == j)
								continue;
							/* End add */
							
							GLPK.intArray_setitem(ind, idx, f[k][i][j]);
							GLPK.intArray_setitem(ind, idx+1, f[k][j][i]);
							GLPK.doubleArray_setitem(val, idx, 1);
							GLPK.doubleArray_setitem(val, idx+1, -1);
							idx += 2;
						}
						GLPK.glp_set_mat_row(prob, constraint, idx-1, ind, val);
					}
				}
			}
			
			/*//flow reserve 1
			for (int k=0;k<reqLinksNum; k++){
				for (int i=0;i<augGraph; i++){ 
					IloLinearNumExpr capReq = cplex.linearNumExpr();
					if (i!=o[k]&&i!=d[k]){
						for (int j=0;j<augGraph; j++){
							capReq.addTerm(1,f[k][i][j]);
							capReq.addTerm(-1,f[k][j][i]);
						}
						cplex.addEq(capReq,0);
					}
				}
			}*/
			
			
			// (4.2)
			double[][] tmpReqLinks = getAvailableBandwidthTable(request);
			
			for (int k=0;k<reqLinksNum; k++){
				int constraint = GLPK.glp_add_rows(prob, 1);
				GLPK.glp_set_row_name(prob, constraint, "r_(4.2)_"+constraint);
				GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_FX, tmpReqLinks[o[k]][d[k]], tmpReqLinks[o[k]][d[k]]);
				ind = GLPK.new_intArray(augGraph*2+1);
				val = GLPK.new_doubleArray(augGraph*2+1);
				int idx = 1;
				for (int w=0;w<augGraph;w++){
					if(o[k] == w)
						continue;
					
					GLPK.intArray_setitem(ind, idx, f[k][o[k]][w]);
					GLPK.intArray_setitem(ind, idx+1, f[k][w][o[k]]);
					GLPK.doubleArray_setitem(val, idx, 1);
					GLPK.doubleArray_setitem(val, idx+1, -1);
					idx += 2;
				}
				GLPK.glp_set_mat_row(prob, constraint, idx-1, ind, val);
			}

			/*//flow reserve 2
			for (int k=0;k<reqLinksNum;k++){
				IloLinearNumExpr capReq = cplex.linearNumExpr();
				for (int w=0;w<augGraph;w++){
					capReq.addTerm(1,f[k][o[k]][w]);
					capReq.addTerm(-1,f[k][w][o[k]]);
				}
				double reCap = 0;
				reCap=tmpReqLinks[o[k]][d[k]];
				cplex.addEq(capReq,reCap); 
			}*/
			
			// (4.3)
			
			for (int k=0;k<reqLinksNum; k++){
				int constraint = GLPK.glp_add_rows(prob, 1);
				GLPK.glp_set_row_name(prob, constraint, "r_(4.3)_"+constraint);
				GLPK.glp_set_row_bnds(prob, constraint, GLPKConstants.GLP_FX, -tmpReqLinks[o[k]][d[k]], -tmpReqLinks[o[k]][d[k]]);
				ind = GLPK.new_intArray(augGraph*2+1);
				val = GLPK.new_doubleArray(augGraph*2+1);
				int idx = 1;
				for (int w=0;w<augGraph;w++){
					if(d[k] == w)
						continue;
					GLPK.intArray_setitem(ind, idx, f[k][d[k]][w]);
					GLPK.intArray_setitem(ind, idx+1, f[k][w][d[k]]);
					GLPK.doubleArray_setitem(val, idx, 1);
					GLPK.doubleArray_setitem(val, idx+1, -1);
					idx += 2;
				}
				GLPK.glp_set_mat_row(prob, constraint, idx-1, ind, val);
			}

			/*//flow reserve 3
			for (int k=0;k<reqLinksNum;k++){
				IloLinearNumExpr capReq = cplex.linearNumExpr();
				for (int w=0;w<augGraph;w++){
					capReq.addTerm(1,f[k][d[k]][w]);
					capReq.addTerm(-1,f[k][w][d[k]]);
				}
				double reCap = 0;
				reCap=-tmpReqLinks[o[k]][d[k]];
				cplex.addEq(capReq,reCap); 
			}*/
			
			GLPK.glp_write_lp(prob, (new glp_cpxcp()), "rvine.problem.txt");
			GLPK.glp_set_obj_dir(prob, GLPKConstants.GLP_MIN);
			GLPK.glp_set_obj_name(prob, "rVine obj");
			
			glp_iocp iocp = new glp_iocp();
			GLPK.glp_init_iocp(iocp);
			iocp.setPresolve(GLPKConstants.GLP_ON);
			int ret = GLPK.glp_intopt(prob, iocp);
			
			System.out.println("ret: "+ret);
			String nameProb = GLPK.glp_get_obj_name(prob);
			double valProb =  GLPK.glp_get_obj_val(prob);
			System.out.println(nameProb+" = "+valProb);
			
			//Solve the Model
			if ( ret != 0 ) {
				denial++;
				denials1++;
				denied=true;
				System.out.println("denial A "  +denial);
				GLPK.glp_delete_prob(prob); 
			} else {
				nameProb = GLPK.glp_get_obj_name(prob);
				valProb =  GLPK.glp_get_obj_val(prob);
				System.out.println(nameProb+" = "+valProb);
				Double[][][] xVar = new Double[reqLinksNum][augGraph][augGraph];
				Double[][][] fVar = new Double[reqLinksNum][augGraph][augGraph];
				for (int k=0; k<reqLinksNum; k++){
					for (int u=0; u<augGraph; u++){
						for (int v=0; v<augGraph; v++){
							System.out.println("idx x["+k+"]["+u+"]["+v+"]: "+x[k][u][v]);
							
							if(x[k][u][v] != 0)
								xVar[k][u][v] = GLPK.glp_mip_col_val(prob, x[k][u][v]); //cplex.getValues(x[k][i]);
							else 
								xVar[k][u][v] = null;
							
							System.out.println("idx f["+k+"]["+u+"]["+v+"]: "+f[k][u][v]);
							
							if(f[k][u][v] != 0)
								fVar[k][u][v] = GLPK.glp_mip_col_val(prob, f[k][u][v]);
							else 
								fVar[k][u][v] = null;
							
							System.out.println("xVar["+k+"]["+u+"]["+v+"]: "+xVar[k][u][v]);
							System.out.println("fVar["+k+"]["+u+"]["+v+"]: "+fVar[k][u][v]);
						}
					}
				}
				
				GLPK.glp_delete_prob(prob);
			
				nodeMapping = myNodeMapping(tmpSubNodesList, substrateCopy, tmpReqNodes,reqLinksNum, xVar, fVar);
				if (nodeMapping==null){
					denial++;
					algo_denials++;
					System.out.println("denial B   " +denial);
					denied = true;
				} else {
					System.out.println("nodeMapping is not null");
					tmpSubNodesList = (ArrayList<Node>) getNodes(substrateCopy);
					Collections.sort(tmpSubNodesList, new NodeComparator());	
					
					System.out.println("prob1.0.1");
					
					glp_prob prob1 = GLPK.glp_create_prob();
					GLPK.glp_set_prob_name(prob1, "rVine Intern");
					GLPK._glp_lpx_set_real_parm(prob1, GLPK.LPX_K_TMLIM, 600);
					GLPK._glp_lpx_set_real_parm(prob1, GLPK.LPX_K_OBJUL, Double.MAX_VALUE);
					GLPK._glp_lpx_set_real_parm(prob1, GLPK.LPX_K_OBJLL, -1*Double.MAX_VALUE);
				
					//create f continuous variable, with bounds lb and ub
					//////////////////////////////////////////////////////////////////
					
					System.out.println("prob1.0.2");
					
					System.out.println("initSubNodeNum: "+initSubNodeNum);
					System.out.println("reqLinksNum: "+reqLinksNum);
					
					int[][][] f_mcf = new int[reqLinksNum][][];
					
					for(int k=0; k<reqLinksNum; k++) {
						f_mcf[k] = new int[initSubNodeNum][];
						for (int u=0; u<initSubNodeNum; u++){
							f_mcf[k][u] = new int[initSubNodeNum];
							for (int v=0; v<initSubNodeNum; v++){
								f_mcf[k][u][v] = GLPK.glp_add_cols(prob1, 1);
			                    name = "f_mcf[" + k + "," + u + "," + v + "]";
			                    GLPK.glp_set_col_name(prob1, f_mcf[k][u][v], name);
			                    GLPK.glp_set_col_kind(prob1, f_mcf[k][u][v], GLPKConstants.GLP_CV);
			                    GLPK.glp_set_col_bnds(prob1, f_mcf[k][u][v], GLPKConstants.GLP_DB, 0, Double.MAX_VALUE);
							}
						}
					}
					
					System.out.println("prob1.1");
					
					/*IloNumVar[][][] f_mcf = new IloNumVar[reqLinksNum][][];
					for (int k=0;k<reqLinksNum;k++){
						f_mcf[k]=new IloNumVar[initSubNodeNum][];
						for (int i=0;i<initSubNodeNum;i++){
							f_mcf[k][i]=cplex1.numVarArray(initSubNodeNum, 0, Double.MAX_VALUE);
						}
					}*/
					////////////////////////////////////////////////////////////////////////////////
					
					for (int i=0; i<initSubNodeNum; i++) { 
						for (int j=0; j<initSubNodeNum; j++) {
							for (int k =0; k<reqLinksNum; k++) {
								 GLPK.glp_set_obj_coef(prob1, f_mcf[k][i][j], 1.0/(augCapTable[i+reqNodeNum][j+reqNodeNum]+Double.MIN_VALUE));
							}
						}
					}
					
					/*IloLinearNumExpr flows_mcf = cplex1.linearNumExpr();
	
					for (int i=0;i<initSubNodeNum; i++){ 
						for (int j=0;j<initSubNodeNum; j++){
							for (int k =0; k<reqLinksNum; k++) {
	//						flows_mcf.addTerm(1.0, f_mcf[k][i][j]);
							flows_mcf.addTerm(1.0/(augCapTable[i+reqNodeNum][j+reqNodeNum]+Double.MIN_VALUE), f_mcf[k][i][j]);
							}
						}
					}*/
					
					//create objective minimization
					//cplex1.addMinimize(flows_mcf);
	
					int[] o2=new int[reqLinksNum];
					int[] d2=new int[reqLinksNum];
	
	/////////////////////////////////////////////////////////////////////////////////////////
	//////If you 're solving the relaxed problem, xVar may take the 0.99999... value/////////
	///////////////////////////////////////////////////////////////////////////////////////
	
					for (int i=0; i<o.length;i++) {
						if (nodeMapping.containsKey(tmpReqNodesList.get(o[i]))) {
							o2[i] = nodeMapping.get(tmpReqNodesList.get(o[i])).getId()-reqNodeNum;
						}
					}
					
					for (int i=0; i<d.length;i++) {
						if (nodeMapping.containsKey(tmpReqNodesList.get(d[i]))){
							d2[i]=nodeMapping.get(tmpReqNodesList.get(d[i])).getId()-reqNodeNum;
						}
					}
					
					/*for (int i=0; i<o.length;i++){
					  if (NodeMapping.containsKey(tmpReqNodesList.get(o[i]))){
					   o2[i]=NodeMapping.get(tmpReqNodesList.get(o[i])).getId()-reqNodeNum;
					  }
				     }
				     for (int i=0; i<d.length;i++){
				      if (NodeMapping.containsKey(tmpReqNodesList.get(d[i]))){
				       d2[i]=NodeMapping.get(tmpReqNodesList.get(d[i])).getId()-reqNodeNum;
				      }
				     }*/
					
					System.out.println("prob1.2");
					
					//flow reservation1
					
					for (int k=0;k<reqLinksNum; k++){
						for (int i=0;i<initSubNodeNum; i++){
							if(o2[k]!=i && d2[k]!=i){
								int constraint = GLPK.glp_add_rows(prob1, 1);
								GLPK.glp_set_row_bnds(prob1, constraint, GLPKConstants.GLP_FX, 0, 0);
								ind = GLPK.new_intArray(initSubNodeNum*2+1);
								val = GLPK.new_doubleArray(initSubNodeNum*2+1);
								int len = 1;
								for(int j = 0; j<initSubNodeNum; j++) {
									if(i == j)
										continue;
									
									GLPK.intArray_setitem(ind, len, f_mcf[k][i][j]);
									GLPK.intArray_setitem(ind, len+1, f_mcf[k][j][i]);
									GLPK.doubleArray_setitem(val, len, 1);
									GLPK.doubleArray_setitem(val, len+1, -1);
									len += 2;
								}
								GLPK.glp_set_mat_row(prob1, constraint, len-1, ind, val);
							}
						}
					}
					
					/*for (int k=0;k<reqLinksNum;k++){
						for (int i=0;i<initSubNodeNum;i++){
							if ((o2[k]!=i)&&(d2[k]!=i)){
								IloLinearNumExpr capReq = cplex1.linearNumExpr();
								//if ((o2[k]-reqNodeNum!=i)&&(d2[k]-reqNodeNum!=i)){
								for (int j=0;j<initSubNodeNum;j++){
									capReq.addTerm(1,f_mcf[k][i][j]);
									capReq.addTerm(-1,f_mcf[k][j][i]);
								}
								cplex1.addEq(capReq, 0);
							}
						}
					}*/
					
					System.out.println("prob1.3");
	
					//flow reservation2
					
					for(int k=0;k<reqLinksNum; k++) {
						int constraint = GLPK.glp_add_rows(prob1, 1);
						GLPK.glp_set_row_bnds(prob1, constraint, GLPKConstants.GLP_FX, tmpReqLinks[o[k]][d[k]], tmpReqLinks[o[k]][d[k]]);
						ind = GLPK.new_intArray(initSubNodeNum*2+1);
						val = GLPK.new_doubleArray(initSubNodeNum*2+1);
						
						System.out.println("initSubNodeNum: "+initSubNodeNum);
						int idx = 1;
						for(int i=0;i<initSubNodeNum;i++) {
							if(o2[k] == i)
								continue;
							
							System.out.println("idx: "+idx+" "+o2[k]+" "+i+" "+k);
							GLPK.intArray_setitem(ind, idx, f_mcf[k][o2[k]][i]);
							GLPK.intArray_setitem(ind, idx+1, f_mcf[k][i][o2[k]]);
							GLPK.doubleArray_setitem(val, idx, 1);
							GLPK.doubleArray_setitem(val, idx+1, -1);
							idx += 2;
						}
						GLPK.glp_set_mat_row(prob1, constraint, idx-1, ind, val);
					}
					
					/*for(int k=0;k<reqLinksNum;k++){
						IloLinearNumExpr capReq = cplex1.linearNumExpr();
						for (int i=0;i<initSubNodeNum;i++){
							capReq.addTerm(1,f_mcf[k][o2[k]][i]);
							//capReq.addTerm(1,f_mcf[k][o2[k]-reqNodeNum][i]);
							capReq.addTerm(-1,f_mcf[k][i][o2[k]]);
							//capReq.addTerm(-1,f_mcf[k][i][o2[k]-reqNodeNum]);
						}
						double reCap = 0;
						reCap=tmpReqLinks[o[k]][d[k]];
						cplex1.addEq(capReq,reCap);
					}*/
					
					System.out.println("prob1.4");
		
					//flow reservation3
					
					for (int k=0;k<reqLinksNum; k++){
						int constraint = GLPK.glp_add_rows(prob1, 1);
						GLPK.glp_set_row_bnds(prob1, constraint, GLPKConstants.GLP_FX, -tmpReqLinks[o[k]][d[k]], -tmpReqLinks[o[k]][d[k]]);
						ind = GLPK.new_intArray(initSubNodeNum*2+1);
						val = GLPK.new_doubleArray(initSubNodeNum*2+1);
						int idx = 0;
						for (int i=0;i<initSubNodeNum;i++){
							if(d2[k] == i)
								continue;
							
							GLPK.intArray_setitem(ind, idx, f_mcf[k][d2[k]][i]);
							GLPK.intArray_setitem(ind, idx+1, f_mcf[k][i][d2[k]]);
							GLPK.doubleArray_setitem(val, idx, 1);
							GLPK.doubleArray_setitem(val, idx+1, -1);
							idx += 2;
						}
						GLPK.glp_set_mat_row(prob1, constraint, idx-1, ind, val);
					}
					
					/*for(int k=0;k<reqLinksNum;k++){
						IloLinearNumExpr capReq = cplex1.linearNumExpr();
						for (int i=0;i<initSubNodeNum;i++){
							capReq.addTerm(1,f_mcf[k][d2[k]][i]);
							//capReq.addTerm(1,f_mcf[k][d2[k]-reqNodeNum][i]);
							capReq.addTerm(-1,f_mcf[k][i][d2[k]]);
							//capReq.addTerm(-1,f_mcf[k][i][d2[k]-reqNodeNum]);
						}
						double reCap = 0;
						reCap=-tmpReqLinks[o[k]][d[k]];
						cplex1.addEq(capReq,reCap);
					}*/
					
					System.out.println("prob1.5");
	
					//Link constraint
					
					for (int i=0;i<initSubNodeNum; i++){
						for (int j=0;j<initSubNodeNum; j++){
							if (i ==  j)
								continue;
							
							double capacity =augCapTable[reqNodeNum+i][reqNodeNum+j];
							int constraint = GLPK.glp_add_rows(prob1, 1);
							GLPK.glp_set_row_bnds(prob1, constraint, GLPKConstants.GLP_UP, 0, capacity);
							ind = GLPK.new_intArray(2*reqLinksNum+1);
							val = GLPK.new_doubleArray(2*reqLinksNum+1);
							int idx = 0;
							
							for (int k=0; k<reqLinksNum; k++) {
								GLPK.intArray_setitem(ind, idx, f_mcf[k][i][j]);
							    GLPK.intArray_setitem(ind, idx+1, f_mcf[k][j][i]);
							    GLPK.doubleArray_setitem(val, idx, 1);
							    GLPK.doubleArray_setitem(val, idx+1, 1);
							    idx += 2;
							}
							
							GLPK.glp_set_mat_row(prob1, constraint, idx-1, ind, val);
						}		
					}
					
					/*for (int i=0;i<initSubNodeNum; i++){
						for (int j=0;j<initSubNodeNum; j++){
							IloNumExpr expr1 =cplex1.prod(f_mcf[0][0][0],0);
							IloNumExpr flowSum =cplex1.prod(f_mcf[0][0][0],0);
							for (int k=0;k<reqLinksNum; k++){
								flowSum = cplex1.sum(cplex1.prod(f_mcf[k][i][j],1), 
										cplex1.prod(f_mcf[k][j][i],1));
								expr1 =cplex1.sum(expr1,flowSum);
							}
							double capacity =augCapTable[reqNodeNum+i][reqNodeNum+j];
							cplex1.addLe(expr1,capacity);
						}
					}*/
					
					System.out.println("prob1.6");
					
					GLPK.glp_write_lp(prob1, (new glp_cpxcp()), "rvine.intern.problem.txt");
					GLPK.glp_set_obj_name(prob1, "rVine Intern Problem obj");
					GLPK.glp_set_obj_dir(prob1, GLPKConstants.GLP_MIN);
					
					glp_iocp iocp1 = new glp_iocp();
					GLPK.glp_init_iocp(iocp1);
					iocp1.setPresolve(GLPKConstants.GLP_ON);
					int ret1 = GLPK.glp_intopt(prob1, iocp1);
					
					//Solve the Model
					if ( ret1 == 0 ) {
						//Update the residual bandwidth
						for (int k=0;k<reqLinksNum;k++){
							for (int i=0;i<initSubNodeNum;i++){
								for (int j=0;j<initSubNodeNum;j++){
									if(f_mcf[k][i][j] != 0)
										fi[k][i][j] = GLPK.glp_mip_col_val(prob1, f_mcf[k][i][j]); //cplex1.getValue(f_mcf[k][i][j]);
									else
										fi[k][i][j] = 0;
								}
							}
						}
					} else {
						denial++;
						denials2++;
						System.out.println("denial C "  +denial);
						denied=true;
					}
					
					GLPK.glp_delete_prob(prob1);
				}
			}
		} catch (Exception e) {
			System.err.println("Concert exception caught: " + e);
			e.printStackTrace();
		}

		ResourceMapping resMap = new ResourceMapping();

		if (!denied){
			resMap.setNodeMapping(nodeMapping);
			resMap.setLinkMapping(fi);
			System.out.println("substrateCopy: "+substrateCopy);
			resMap.reserveNodes(substrateCopy);
			resMap.reserveLinks(substrateCopy);
			resMap.accepted();

		}else{
			resMap.denied();
		}
			
		///Take results
		double cost = Cost_Embedding(fi, request, substrateCopy); 
		double avgHops = avgHops(fi);
		
		System.out.println("denial: "+denial);
		System.out.println("cost: "+cost);
		System.out.println("avgHops: "+avgHops);
		System.out.println("algo_denials: "+algo_denials);
		
		return null;
	}

	public static void test1() {
		// jra23 Request (based on a real FEDERICA slice)
		Request request = new Request("jra23Request");
		
		// FEDERICA substrate
	    Substrate substrate = new Substrate("FEDERICA");
	    
	    // Hardcoded Request
	    request.setStartDate(0);
	    request.setEndDate(12);
	    // Nodes and links of the request are generated by random factories
	    RequestNodeFactory nodeFactory = new RequestNodeFactory();
	    RequestLinkFactory linkFactory = new RequestLinkFactory();
	    request.setNodeFactory(nodeFactory);
	    request.setLinkFactory(linkFactory);
	     
	    // router0
	    RequestRouter r0 = (RequestRouter) nodeFactory.create("router");
//	    router0.setCpu(20);
//	    router0.setMemory(20);
	    // router1
	    RequestRouter r1 = (RequestRouter) nodeFactory.create("router");
//	    r1.setCpu(20);
//	    r1.setMemory(20);
	    // sw0
	    RequestSwitch sw0 = (RequestSwitch) nodeFactory.create("switch");
//	    sw0.setCpu(20);
//	    sw0.setMemory(20);
//	    sw0.setVlans(10);
	    // sw1
	    RequestSwitch sw1 = (RequestSwitch) nodeFactory.create("switch");
//	    sw1.setCpu(20);
//	    sw1.setMemory(20);
//	    sw1.setVlans(10);
	    // sw2
	    RequestSwitch sw2 = (RequestSwitch) nodeFactory.create("switch");
//	    sw2.setCpu(20);
//	    sw2.setMemory(20);
//	    sw2.setVlans(10);
	    // vm0
	    VirtualMachine vm0 = (VirtualMachine) nodeFactory.create("virtualMachine");
//	    vm0.setCpu(20);
//	    vm0.setMemory(20);
//	    vm0.setDiskSpace(20);
	    // vm1
	    VirtualMachine vm1 = (VirtualMachine) nodeFactory.create("virtualMachine");
//	    vm1.setCpu(20);
//	    vm1.setMemory(20);
//	    vm1.setDiskSpace(20);
	    // vm2
	    VirtualMachine vm2 = (VirtualMachine) nodeFactory.create("virtualMachine");
//	    vm2.setCpu(20);
//	    vm2.setMemory(20);
//	    vm2.setDiskSpace(20);
	    // vm3
	    VirtualMachine vm3 = (VirtualMachine) nodeFactory.create("virtualMachine");
//	    vm3.setCpu(20);
//	    vm3.setMemory(20);
//	    vm3.setDiskSpace(20);
	    // vm4
	    VirtualMachine vm4 = (VirtualMachine) nodeFactory.create("virtualMachine");
//	    vm4.setCpu(20);
//	    vm4.setMemory(20);
//	    vm4.setDiskSpace(20);
	    // vm5
	    VirtualMachine vm5 = (VirtualMachine) nodeFactory.create("virtualMachine");
//	    vm5.setCpu(20);
//	    vm5.setMemory(20);
//	    vm5.setDiskSpace(20);
	    // vm6
	    VirtualMachine vm6 = (VirtualMachine) nodeFactory.create("virtualMachine");
//	    vm6.setCpu(20);
//	    vm6.setMemory(20);
//	    vm6.setDiskSpace(20);
	    // vm7
	    VirtualMachine vm7 = (VirtualMachine) nodeFactory.create("virtualMachine");
//	    vm7.setCpu(20);
//	    vm7.setMemory(20);
//	    vm7.setDiskSpace(20);

	    // Adding Links with random bw
	    //vm0-sw0
	    RequestLink requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(0,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm0,sw0), EdgeType.UNDIRECTED);
	    //vm1-sw0
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(1,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm1,sw0), EdgeType.UNDIRECTED);
	    //vm2-sw1
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(2,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm2,sw1), EdgeType.UNDIRECTED);
	    //vm3-sw1
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(3,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm3,sw1), EdgeType.UNDIRECTED);
	    //vm4-sw2
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(4,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm4,sw2), EdgeType.UNDIRECTED);
	    //vm5-sw2
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(5,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm5,sw2), EdgeType.UNDIRECTED);
	    //vm6-r1
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(6,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm6,r1), EdgeType.UNDIRECTED);
	    //vm7-r1
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(7,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm7,r1), EdgeType.UNDIRECTED);
	    //r0-r1
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(8,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(r0,r1), EdgeType.UNDIRECTED);
	    //r0-sw0
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(9,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(r0,sw0), EdgeType.UNDIRECTED);
	    //r0-sw1
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(10,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(r0,sw1), EdgeType.UNDIRECTED);
	    //r0-sw2
	    requestLink = (RequestLink) linkFactory.create();
//	    requestLink = new RequestLink(11,20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(r0,sw2), EdgeType.UNDIRECTED);
	    
	    
	    // Hardcoded FEDERICA Substrate
	    /** Portugal (FCCN)**/
	    // sw1.lis.pt
	    SubstrateSwitch sw1LisPt = new SubstrateSwitch(0);
	    sw1LisPt.setName("sw1.lis.pt");
	    sw1LisPt.setLocation(Location.Portugal);
	    sw1LisPt.setCpu(100);
	    sw1LisPt.setMemory(100);
	    sw1LisPt.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    // vnode1.lis.pt
	    Server vnode1LisPt = new Server(1);
	    vnode1LisPt.setName("vnode1.lis.pt");
	    vnode1LisPt.setLocation(Location.Portugal);
	    vnode1LisPt.setCpu(100);
	    vnode1LisPt.setMemory(100);
	    vnode1LisPt.setDiskSpace(100);
	    vnode1LisPt.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    /** Spain - Madrid (RedIRIS) **/
	    // sw1.mad.es
	    SubstrateSwitch sw1MadEs = new SubstrateSwitch(2);
	    sw1MadEs.setName("sw1.mad.es");
	    sw1MadEs.setLocation(Location.Spain);
	    sw1MadEs.setCpu(100);
	    sw1MadEs.setMemory(100);
	    sw1MadEs.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    // vnode1.mad.es
	    Server vnode1MadEs = new Server(3);
	    vnode1MadEs.setName("vnode1.mad.es");
	    vnode1MadEs.setLocation(Location.Spain);
	    vnode1MadEs.setCpu(100);
	    vnode1MadEs.setMemory(100);
	    vnode1MadEs.setDiskSpace(100);
	    vnode1MadEs.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    /** Spain - Barcelona (i2CAT) **/
	    // sw1.bar.es
	    SubstrateSwitch sw1BarEs = new SubstrateSwitch(4);
	    sw1BarEs.setName("sw1.bar.es");
	    sw1BarEs.setLocation(Location.Spain);
	    sw1BarEs.setCpu(100);
	    sw1BarEs.setMemory(100);
	    sw1BarEs.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    // vnode1.bar.es
	    Server vnode1BarEs = new Server(5);
	    vnode1BarEs.setName("vnode1.bar.es");
	    vnode1BarEs.setLocation(Location.Spain);
	    vnode1BarEs.setCpu(100);
	    vnode1BarEs.setMemory(100);
	    vnode1BarEs.setDiskSpace(100);
	    vnode1BarEs.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    // vnode2.bar.es
	    Server vnode2BarEs = new Server(6);
	    vnode2BarEs.setName("vnode2.bar.es");
	    vnode2BarEs.setLocation(Location.Spain);
	    vnode2BarEs.setCpu(100);
	    vnode2BarEs.setMemory(100);
	    vnode2BarEs.setDiskSpace(100);
	    vnode2BarEs.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    /** Ireland (HEANet) **/
	    // sw1.dub.ie
	    SubstrateSwitch sw1DubIe = new SubstrateSwitch(7);
	    sw1DubIe.setName("sw1.dub.ie");
	    sw1DubIe.setLocation(Location.Ireland);
	    sw1DubIe.setCpu(100);
	    sw1DubIe.setMemory(100);
	    sw1DubIe.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    // vnode1.dub.ie
	    Server vnode1DubIe = new Server(8);
	    vnode1DubIe.setName("vnode1.dub.ie");
	    vnode1DubIe.setLocation(Location.Ireland);
	    vnode1DubIe.setCpu(100);
	    vnode1DubIe.setMemory(100);
	    vnode1DubIe.setDiskSpace(100);
	    vnode1DubIe.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    /** Greece (GRNET) **/
	    // sw1.eie.gr
	    SubstrateSwitch sw1EieGr = new SubstrateSwitch(9);
	    sw1EieGr.setName("sw1.eie.gr");
	    sw1EieGr.setLocation(Location.Greece);
	    sw1EieGr.setCpu(100);
	    sw1EieGr.setMemory(100);
	    sw1EieGr.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    // sw1.ntu.gr
	    SubstrateSwitch sw1NtuGr = new SubstrateSwitch(10);
	    sw1NtuGr.setName("sw1.ntu.gr");
	    sw1NtuGr.setLocation(Location.Greece);
	    sw1NtuGr.setCpu(100);
	    sw1NtuGr.setMemory(100);
	    sw1NtuGr.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    // vnode1.ntu.ie
	    Server vnode1NtuGr = new Server(11);
	    vnode1NtuGr.setName("vnode1.ntu.ie");
	    vnode1NtuGr.setLocation(Location.Greece);
	    vnode1NtuGr.setCpu(100);
	    vnode1NtuGr.setMemory(100);
	    vnode1NtuGr.setDiskSpace(100);
	    vnode1NtuGr.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    /** Italy (GARR) **/
	    // r1.mil.it
	    SubstrateRouter r1MilIt = new SubstrateRouter(12);
	    r1MilIt.setName("r1.mil.it");
	    r1MilIt.setLocation(Location.Italy);
	    //r1MilIt.setCpu(100);
	    //r1MilIt.setMemory(100);
	    r1MilIt.setVlans(SimulatorConstants.MAX_ROUTER_VLANS);
	    // vnode1.mil.it
	    Server vnode1MilIt = new Server(13);
	    vnode1MilIt.setName("vnode1.mil.it");
	    vnode1MilIt.setLocation(Location.Italy);
	    vnode1MilIt.setCpu(100);
	    vnode1MilIt.setMemory(100);
	    vnode1MilIt.setDiskSpace(100);
	    vnode1MilIt.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    // vnode2.mil.it
	    Server vnode2MilIt = new Server(14);
	    vnode2MilIt.setName("vnode2.mil.it");
	    vnode2MilIt.setLocation(Location.Italy);
	    vnode2MilIt.setCpu(100);
	    vnode2MilIt.setMemory(100);
	    vnode2MilIt.setDiskSpace(100);
	    vnode2MilIt.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    /** Switzerland (SWITCH) **/
	    // sw1.gen.ch
	    SubstrateSwitch sw1GenCh = new SubstrateSwitch(15);
	    sw1GenCh.setName("sw1.gen.ch");
	    sw1GenCh.setLocation(Location.Switzerland);
	    sw1GenCh.setCpu(100);
	    sw1GenCh.setMemory(100);
	    sw1GenCh.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    // vnode1.gen.ch
	    Server vnode1GenCh = new Server(16);
	    vnode1GenCh.setName("vnode1.gen.ch");
	    vnode1GenCh.setLocation(Location.Switzerland);
	    vnode1GenCh.setCpu(100);
	    vnode1GenCh.setMemory(100);
	    vnode1GenCh.setDiskSpace(100);
	    vnode1GenCh.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    /** Hungary (HUNGARNET) **/
	    // sw1.bud.hu
	    SubstrateSwitch sw1BudHu = new SubstrateSwitch(17);
	    sw1BudHu.setName("sw1.bud.hu");
	    sw1BudHu.setLocation(Location.Hungary);
	    sw1BudHu.setCpu(100);
	    sw1BudHu.setMemory(100);
	    sw1BudHu.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    // vnode1.bud.hu
	    Server vnode1BudHu = new Server(18);
	    vnode1BudHu.setName("vnode1.bud.hu");
	    vnode1BudHu.setLocation(Location.Hungary);
	    vnode1BudHu.setCpu(100);
	    vnode1BudHu.setMemory(100);
	    vnode1BudHu.setDiskSpace(100);
	    vnode1BudHu.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    /** Germany (DFN) **/
	    // r1.erl.de
	    SubstrateRouter r1ErlDe = new SubstrateRouter(19);
	    r1ErlDe.setName("r1.erl.de");
	    r1ErlDe.setLocation(Location.Germany);
	    //r1ErlDe.setCpu(100);
	    //r1ErlDe.setMemory(100);
	    r1ErlDe.setVlans(SimulatorConstants.MAX_ROUTER_VLANS);
	    // vnode1.erl.de
	    Server vnode1ErlDe = new Server(20);
	    vnode1ErlDe.setName("vnode1.erl.de");
	    vnode1ErlDe.setLocation(Location.Germany);
	    vnode1ErlDe.setCpu(100);
	    vnode1ErlDe.setMemory(100);
	    vnode1ErlDe.setDiskSpace(100);
	    vnode1ErlDe.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    // vnode2.erl.de
	    Server vnode2ErlDe = new Server(21);
	    vnode2ErlDe.setName("vnode2.erl.de");
	    vnode2ErlDe.setLocation(Location.Germany);
	    vnode2ErlDe.setCpu(100);
	    vnode2ErlDe.setMemory(100);
	    vnode2ErlDe.setDiskSpace(100);
	    vnode2ErlDe.setVlans(SimulatorConstants.MAX_SERVER_VLANS);	    
	    /** Czech Republic (CESNET) **/
	    // r1.pra.cz
	    SubstrateRouter r1PraCz = new SubstrateRouter(22);
	    r1PraCz.setName("r1.pra.cz");
	    r1PraCz.setLocation(Location.Czech_Republic);
	    //r1PraCz.setCpu(100);
	    //r1PraCz.setMemory(100);
	    r1PraCz.setVlans(SimulatorConstants.MAX_ROUTER_VLANS);	    
	    // vnode1.pra.cz
	    Server vnode1PraCz = new Server(23);
	    vnode1PraCz.setName("vnode1.pra.cz");
	    vnode1PraCz.setLocation(Location.Czech_Republic);
	    vnode1PraCz.setCpu(100);
	    vnode1PraCz.setMemory(100);
	    vnode1PraCz.setDiskSpace(100);
	    vnode1PraCz.setVlans(SimulatorConstants.MAX_SERVER_VLANS);	    
	    // vnode2.pra.cz
	    Server vnode2PraCz = new Server(24);
	    vnode2PraCz.setName("vnode2.pra.cz");
	    vnode2PraCz.setLocation(Location.Czech_Republic);
	    vnode2PraCz.setCpu(100);
	    vnode2PraCz.setMemory(100);
	    vnode2PraCz.setDiskSpace(100);
	    vnode2PraCz.setVlans(SimulatorConstants.MAX_SERVER_VLANS);	    
	    /** Poland (PSNC) **/
	    // r1.poz.pl
	    SubstrateRouter r1PozPl = new SubstrateRouter(25);
	    r1PozPl.setName("r1.poz.pl");
	    r1PozPl.setLocation(Location.Poland);
	    //r1PozPl.setCpu(100);
	    //r1PozPl.setMemory(100);
	    r1PozPl.setVlans(SimulatorConstants.MAX_ROUTER_VLANS);	
	    // vnode1.poz.pl
	    Server vnode1PozPl = new Server(26);
	    vnode1PozPl.setName("vnode1.poz.pl");
	    vnode1PozPl.setLocation(Location.Poland);
	    vnode1PozPl.setCpu(100);
	    vnode1PozPl.setMemory(100);
	    vnode1PozPl.setDiskSpace(100);
	    vnode1PozPl.setVlans(SimulatorConstants.MAX_SERVER_VLANS);	    
	    // vnode2.poz.pl
	    Server vnode2PozPl = new Server(27);
	    vnode2PozPl.setName("vnode2.poz.pl");
	    vnode2PozPl.setLocation(Location.Poland);
	    vnode2PozPl.setCpu(100);
	    vnode2PozPl.setMemory(100);
	    vnode2PozPl.setDiskSpace(100);
	    vnode2PozPl.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    // vnode3.poz.pl
	    Server vnode3PozPl = new Server(28);
	    vnode3PozPl.setName("vnode3.poz.pl");
	    vnode3PozPl.setLocation(Location.Poland);
	    vnode3PozPl.setCpu(100);
	    vnode3PozPl.setMemory(100);
	    vnode3PozPl.setDiskSpace(100);
	    vnode3PozPl.setVlans(SimulatorConstants.MAX_SERVER_VLANS);	
	    // vnode4.poz.pl
	    Server vnode4PozPl = new Server(29);
	    vnode4PozPl.setName("vnode4.poz.pl");
	    vnode4PozPl.setLocation(Location.Poland);
	    vnode4PozPl.setCpu(100);
	    vnode4PozPl.setMemory(100);
	    vnode4PozPl.setDiskSpace(100);
	    vnode4PozPl.setVlans(SimulatorConstants.MAX_SERVER_VLANS);	
	    /** Sweden (KTH) **/
	    // sw1.sth.se
	    SubstrateSwitch sw1SthSe = new SubstrateSwitch(30);
	    sw1SthSe.setName("sw1.sth.se");
	    sw1SthSe.setLocation(Location.Sweden);
	    sw1SthSe.setCpu(100);
	    sw1SthSe.setMemory(100);
	    sw1SthSe.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    // vnode1.sth.se
	    Server vnode1SthSe = new Server(31);
	    vnode1SthSe.setName("vnode1.sth.se");
	    vnode1SthSe.setLocation(Location.Sweden);
	    vnode1SthSe.setCpu(100);
	    vnode1SthSe.setMemory(100);
	    vnode1SthSe.setDiskSpace(100);
	    vnode1SthSe.setVlans(SimulatorConstants.MAX_SERVER_VLANS);	    
	    // vnode2.sth.se
	    Server vnode2SthSe = new Server(32);
	    vnode2SthSe.setName("vnode2.sth.se");
	    vnode2SthSe.setLocation(Location.Sweden);
	    vnode2SthSe.setCpu(100);
	    vnode2SthSe.setMemory(100);
	    vnode2SthSe.setDiskSpace(100);
	    vnode2SthSe.setVlans(SimulatorConstants.MAX_SERVER_VLANS);	    
	    
	   
	    // Adding links & interfaces
	    // sw1.lis.pt - vnode1.lis.pt
	    SubstrateLink link = new SubstrateLink(0,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1LisPt,vnode1LisPt), EdgeType.UNDIRECTED);
	    
	    // sw1.lis.pt - sw1.mad.es
	    link = new SubstrateLink(1,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1LisPt,sw1MadEs), EdgeType.UNDIRECTED);
	    
	    // vnode1.mad.es - sw1.mad.es (1)
	    link = new SubstrateLink(2,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1MadEs,vnode1MadEs), EdgeType.UNDIRECTED);
	    
	    // vnode1.mad.es - sw1.mad.es (2)
	    link = new SubstrateLink(3,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1MadEs,vnode1MadEs), EdgeType.UNDIRECTED);
	    
	    // vnode1.mad.es - sw1.mad.es (3)
	    link = new SubstrateLink(4,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1MadEs,vnode1MadEs), EdgeType.UNDIRECTED);
	    
	    // sw1.mad.es - sw1.bar.es (1)
	    link = new SubstrateLink(5,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1MadEs,sw1BarEs), EdgeType.UNDIRECTED);
	    
	    // sw1.mad.es - sw1.bar.es (2)
	    link = new SubstrateLink(6,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1MadEs,sw1BarEs), EdgeType.UNDIRECTED);
	    
	    // vnode1.bar.es - sw1.bar.es
	    link = new SubstrateLink(7,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode1BarEs,sw1BarEs), EdgeType.UNDIRECTED);
	    
	    // vnode2.bar.es - sw1.bar.es
	    link = new SubstrateLink(8,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode2BarEs,sw1BarEs), EdgeType.UNDIRECTED);	    
	    
	    // sw1.mad.es - sw1.ntu.gr
	    link = new SubstrateLink(9,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1MadEs,sw1NtuGr), EdgeType.UNDIRECTED);
	    
	    // sw1.mad.es - sw1.dub.ie
	    link = new SubstrateLink(10,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1MadEs,sw1DubIe), EdgeType.UNDIRECTED);	    

	    // sw1.mad.es - r1.mil.it
	    link = new SubstrateLink(11,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1MadEs,r1MilIt), EdgeType.UNDIRECTED);
	    
	    // sw1.ntu.gr - vnode1.ntu.gr
	    link = new SubstrateLink(12,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode1NtuGr,sw1NtuGr), EdgeType.UNDIRECTED);
	    
	    // sw1.ntu.gr - r1.pra.cz
	    link = new SubstrateLink(13,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1PraCz,sw1NtuGr), EdgeType.UNDIRECTED);	    
	    
	    // sw1.eie.gr - sw1.bud.hu
	    link = new SubstrateLink(14,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1BudHu,sw1EieGr), EdgeType.UNDIRECTED);	    
	    
	    // sw1.bud.hu - vnode1.bud.hu (1)
	    link = new SubstrateLink(15,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1BudHu,vnode1BudHu), EdgeType.UNDIRECTED);	    
	    
	    // sw1.bud.hu - vnode1.bud.hu (2)
	    link = new SubstrateLink(16,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1BudHu,vnode1BudHu), EdgeType.UNDIRECTED);	
	    
	    // sw1.bud.hu - vnode1.bud.hu (3)
	    link = new SubstrateLink(17,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1BudHu,vnode1BudHu), EdgeType.UNDIRECTED);	
	    
	    // sw1.bud.hu - sw1.gen.ch
	    link = new SubstrateLink(18,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1BudHu,sw1GenCh), EdgeType.UNDIRECTED);	    
	
	    // sw1.gen.ch - vnode1.gen.ch
	    link = new SubstrateLink(19,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode1GenCh,sw1GenCh), EdgeType.UNDIRECTED);
	    
	    // sw1.gen.ch - r1.erl.de
	    link = new SubstrateLink(20,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1ErlDe,sw1GenCh), EdgeType.UNDIRECTED);	    
	    
	    // sw1.gen.ch - sw1.dub.ie
	    link = new SubstrateLink(21,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1DubIe,sw1GenCh), EdgeType.UNDIRECTED);	    
	    
	    // sw1.dub.ie - vnode1.dub.ie
	    link = new SubstrateLink(22,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1DubIe,vnode1DubIe), EdgeType.UNDIRECTED);    
	    
	    // sw1.dub.ie - sw1.sth.se
	    link = new SubstrateLink(23,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1DubIe,sw1SthSe), EdgeType.UNDIRECTED);	    
	    
	    // sw1.sth.se - vnode1.sth.se
	    link = new SubstrateLink(24,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode1SthSe,sw1SthSe), EdgeType.UNDIRECTED);	    
	    
	    // sw1.sth.se - vnode2.sth.se
	    link = new SubstrateLink(25,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode2SthSe,sw1SthSe), EdgeType.UNDIRECTED);	    
	    
	    // sw1.sth.se - r1.poz.pl
	    link = new SubstrateLink(25,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1PozPl,sw1SthSe), EdgeType.UNDIRECTED);    
	    
	    // r1.mil.it - vnode1.mil.it
	    link = new SubstrateLink(26,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1MilIt,vnode1MilIt), EdgeType.UNDIRECTED);    
	    
	    // r1.mil.it - vnode2.mil.it
	    link = new SubstrateLink(27,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1MilIt,vnode2MilIt), EdgeType.UNDIRECTED); 	    
	    
	    // r1.mil.it - r1.poz.pl
	    link = new SubstrateLink(28,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1MilIt,r1PozPl), EdgeType.UNDIRECTED); 
	    
	    // r1.mil.it - r1.pra.cz
	    link = new SubstrateLink(29,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1MilIt,r1PraCz), EdgeType.UNDIRECTED);
	    
	    // r1.pra.cz - vnode1.pra.cz
	    link = new SubstrateLink(30,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode1PraCz,r1PraCz), EdgeType.UNDIRECTED);	    
	    
	    // r1.pra.cz - vnode2.pra.cz
	    link = new SubstrateLink(31,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode2PraCz,r1PraCz), EdgeType.UNDIRECTED);    
	    
	    // r1.pra.cz - r1.poz.pl
	    link = new SubstrateLink(32,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1PozPl,r1PraCz), EdgeType.UNDIRECTED);    
	    
	    // r1.pra.cz - r1.erl.de
	    link = new SubstrateLink(33,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1ErlDe,r1PraCz), EdgeType.UNDIRECTED);	    
	    
	    // r1.erl.de - vnode1.erl.de
	    link = new SubstrateLink(34,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1ErlDe,vnode1ErlDe), EdgeType.UNDIRECTED); 
	    
	    // r1.erl.de - vnode2.erl.de
	    link = new SubstrateLink(35,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1ErlDe,vnode2ErlDe), EdgeType.UNDIRECTED);   
	    
	    // r1.erl.de - r1.poz.pl
	    link = new SubstrateLink(36,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1ErlDe,r1PozPl), EdgeType.UNDIRECTED);	    
	    
	    // r1.poz.pl - vnode1.poz.pl
	    link = new SubstrateLink(37,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode1PozPl,r1PozPl), EdgeType.UNDIRECTED);  
	    
	    // r1.poz.pl - vnode2.poz.pl
	    link = new SubstrateLink(38,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode2PozPl,r1PozPl), EdgeType.UNDIRECTED);
	    
	    // r1.poz.pl - vnode3.poz.pl
	    link = new SubstrateLink(39,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode3PozPl,r1PozPl), EdgeType.UNDIRECTED);
	    
	    // r1.poz.pl - vnode4.poz.pl
	    link = new SubstrateLink(40,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(vnode4PozPl,r1PozPl), EdgeType.UNDIRECTED);
	    
	    // r1.erl.de - r1.mil.it
	    link = new SubstrateLink(41,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1ErlDe,r1MilIt), EdgeType.UNDIRECTED);
	    
	    RVine rvine = new RVine();
	    rvine.embed(request.getGraph(), substrate.getGraph());
	}
	
	public static void test2() {
		
		Request request = new Request("myrequest");
	    request.setStartDate(0);
	    request.setEndDate(12);
	    RequestNodeFactory nodeFactory = new RequestNodeFactory();
	    RequestLinkFactory linkFactory = new RequestLinkFactory();
	    request.setNodeFactory(nodeFactory);
	    request.setLinkFactory(linkFactory);
	    
	    // sw0
	    RequestSwitch sw0 = (RequestSwitch) nodeFactory.create("switch");
	    sw0.setCpu(50);
	    sw0.setMemory(50);
	    // vm0
	    VirtualMachine vm0 = (VirtualMachine) nodeFactory.create("virtualMachine");
	    vm0.setCpu(50);
	    vm0.setMemory(50);
	    vm0.setDiskSpace(50);
	    // vm1
	    VirtualMachine vm1 = (VirtualMachine) nodeFactory.create("virtualMachine");
	    vm1.setCpu(50);
	    vm1.setMemory(50);
	    vm1.setDiskSpace(50);

	    // Adding Links with random bw
	    //vm0-sw0
	    RequestLink requestLink = (RequestLink) linkFactory.create();
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm0, sw0), EdgeType.UNDIRECTED);
	    //vm1-sw0
	    requestLink = (RequestLink) linkFactory.create();
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm1, sw0), EdgeType.UNDIRECTED);
	    
	    Substrate substrate = new Substrate("mysubstrate");
	    
	    SubstrateRouter r1MilIt = new SubstrateRouter(0);
	    r1MilIt.setName("r1.mil.it");
	    r1MilIt.setLocation(Location.Italy);
	    //r1MilIt.setCpu(100);
	    //r1MilIt.setMemory(100);
	    r1MilIt.setVlans(SimulatorConstants.MAX_ROUTER_VLANS);
	    
	    SubstrateSwitch sw1LisPt = new SubstrateSwitch(1);
	    sw1LisPt.setName("sw1.lis.pt");
	    sw1LisPt.setLocation(Location.Portugal);
	    sw1LisPt.setCpu(100);
	    sw1LisPt.setMemory(100);
	    sw1LisPt.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    
	    SubstrateSwitch sw1MadEs = new SubstrateSwitch(2);
	    sw1MadEs.setName("sw1.mad.es");
	    sw1MadEs.setLocation(Location.Spain);
	    sw1MadEs.setCpu(100);
	    sw1MadEs.setMemory(100);
	    sw1MadEs.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    
	    Server vnode1LisPt = new Server(3);
	    vnode1LisPt.setName("vnode1.lis.pt");
	    vnode1LisPt.setLocation(Location.Portugal);
	    vnode1LisPt.setCpu(100);
	    vnode1LisPt.setMemory(100);
	    vnode1LisPt.setDiskSpace(100);
	    vnode1LisPt.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    
	    Server vnode1MadEs = new Server(4);
	    vnode1MadEs.setName("vnode1.mad.es");
	    vnode1MadEs.setLocation(Location.Spain);
	    vnode1MadEs.setCpu(100);
	    vnode1MadEs.setMemory(100);
	    vnode1MadEs.setDiskSpace(100);
	    vnode1MadEs.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    
	    Server vnode1BarEs = new Server(5);
	    vnode1BarEs.setName("vnode1.bar.es");
	    vnode1BarEs.setLocation(Location.Spain);
	    vnode1BarEs.setCpu(100);
	    vnode1BarEs.setMemory(100);
	    vnode1BarEs.setDiskSpace(100);
	    vnode1BarEs.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    
	    Server vnode2BarEs = new Server(6);
	    vnode2BarEs.setName("vnode2.bar.es");
	    vnode2BarEs.setLocation(Location.Spain);
	    vnode2BarEs.setCpu(100);
	    vnode2BarEs.setMemory(100);
	    vnode2BarEs.setDiskSpace(100);
	    vnode2BarEs.setVlans(SimulatorConstants.MAX_SERVER_VLANS);	    
	    
	    SubstrateLink link;
	    
	    link = new SubstrateLink(0,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1MilIt, sw1LisPt), EdgeType.UNDIRECTED);
	    
	    // sw1.lis.pt - vnode1.lis.pt
	    link = new SubstrateLink(1,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(r1MilIt, sw1MadEs), EdgeType.UNDIRECTED);
	    
	    // vnode1.mad.es - sw1.mad.es
	    link = new SubstrateLink(2,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1MadEs, vnode1MadEs), EdgeType.UNDIRECTED);
	    
	    // sw1.mad.es - sw1.bar.es
	    link = new SubstrateLink(3,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1MadEs, vnode1LisPt), EdgeType.UNDIRECTED);
	    
	    // vnode1.bar.es - sw1.bar.es
	    link = new SubstrateLink(4,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1LisPt, vnode1BarEs), EdgeType.UNDIRECTED);
	    
	    // vnode2.bar.es - sw1.bar.es
	    link = new SubstrateLink(5,100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1LisPt, vnode2BarEs), EdgeType.UNDIRECTED);
	    
	    //substrate.print();
	    
	    RVine rvine = new RVine();
	    rvine.embed(request.getGraph(), substrate.getGraph());
	}
	
	public static void test3() {	

		Request request = new Request("myrequest");
	    request.setStartDate(0);
	    request.setEndDate(12);
	    RequestNodeFactory nodeFactory = new RequestNodeFactory();
	    RequestLinkFactory linkFactory = new RequestLinkFactory();
	    request.setNodeFactory(nodeFactory);
	    request.setLinkFactory(linkFactory);
	    
	    // sw0
	    RequestRouter sw0 = (RequestRouter) nodeFactory.create("router");
	    //sw0.setCpu(100);
	    //sw0.setMemory(100);
	    // vm0
	    VirtualMachine vm0 = (VirtualMachine) nodeFactory.create("virtualMachine");
	    vm0.setCpu(100);
	    vm0.setMemory(100);
	    vm0.setDiskSpace(100);

	    // Adding Links with random bw
	    //vm0-sw0
	    RequestLink requestLink = new RequestLink(0, 20);
	    request.getGraph().addEdge(requestLink,new Pair<Node>(vm0, sw0), EdgeType.UNDIRECTED);
	    
	    Substrate substrate = new Substrate("mysubstrate");
	    
	    SubstrateRouter sw1LisPt = new SubstrateRouter(0);
	    sw1LisPt.setName("sw1.lis.pt");
	    sw1LisPt.setLocation(Location.Portugal);
	    //sw1LisPt.setCpu(100);
	    //sw1LisPt.setMemory(100);
	    sw1LisPt.setLogicalInstances(15); //maximum logical instances= 15
	    sw1LisPt.setVlans(SimulatorConstants.MAX_SWITCH_VLANS);
	    
	    Server vnode1LisPt = new Server(1);
	    vnode1LisPt.setName("vnode1.lis.pt");
	    vnode1LisPt.setLocation(Location.Portugal);
	    vnode1LisPt.setCpu(100);
	    vnode1LisPt.setMemory(100);
	    vnode1LisPt.setDiskSpace(100);
	    vnode1LisPt.setVlans(SimulatorConstants.MAX_SERVER_VLANS);
	    
	    SubstrateLink link = new SubstrateLink(0, 100);
	    substrate.getGraph().addEdge(link,new Pair<Node>(sw1LisPt, vnode1LisPt), EdgeType.UNDIRECTED);
	    
	    RVine rvine = new RVine();
	    rvine.embed(request.getGraph(), substrate.getGraph());
	}
	
	public static void main(String[] args) {
		//test1();
		//test2();
		test3();
	}
}